package com.tcm.day05;

public class Code02_BitAccumulate {

    public static class BitAccumulate {

        // a+b = a和b的无进位加 + a和b的进位
        public static int add(int a, int b) {
            int sum = 0;
            while (b != 0) { // 没有进位
                sum = a ^ b; // a和b的无进位加
                b = (a & b) << 1; // a和b的进位
                a = sum;
            }
            return sum;
        }

        // a-b = a+(-b) = a + (~b+1)
        public static int minus(int a, int b) {
            return add(a, add(~b, 1));
        }

        //       0001101
        //             *
        //       0101001
        //      -----------
        //       0001101
        //      0000000
        //     0000000
        //    0001101
        //   0000000
        //  0001101
        // 0000000
        public static int multi(int a, int b) {
            int sum = 0;
            while (b != 0) {
                if ((b & 1) != 0) { // 表示最末尾不是0
                    sum = add(sum, a);
                }
                a <<= 1;
                b >>>= 1;
            }
            return sum;
        }

        public static int div(int a, int b) {
            int x = isNeg(a) ? negNum(a) : a;
            int y = isNeg(b) ? negNum(b) : b;
            int res = 0;
            for (int i = 30; i >= 0; i = minus(i, 1)) {
                if ((x >> i) >= y) {
                    res |= (1 << i);
                    x = minus(x, y << i);
                }
            }
            return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
        }

        public static int divide(int a, int b) {
            if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE) {
                return 1;
            } else if (b == Integer.MIN_VALUE) {
                return 0;
            } else if (a == Integer.MIN_VALUE) {
                if (b == negNum(1)) {
                    return Integer.MAX_VALUE;
                } else {
                    int c = div(add(a, 1), b);
                    return add(c, div(minus(a, multi(c, b)), b));
                }
            }else{
                return div(a,b);
            }
        }

        public static boolean isNeg(int num) {
            return num < 0;
        }

        public static int negNum(int num) {
            return add(~num, 1);
        }
    }

}
